package com.cci.kangdao.utilTool;

import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author XiaoshanDu
 * @date 2019/2/10
 */
public class CollectionUtils extends org.apache.commons.collections.CollectionUtils {

    public static int search(Object[] array, Object key) {
        if (array == null || array.length <= 0) {
            return -1;
        }

        for (int i = 0; i < array.length; i++) {
            if (key.equals(array[i])) {
                return i;
            }
        }
        return -1;
    }

    public static <T> List<T> retainStart(List<T> list) {
        return retainStart(list, 1);
    }

    public static <T> List<T> retainEnd(List<T> list) {
        return retainEnd(list, 1);
    }

    public static <T> List<T> retainStart(List<T> list, int no) {
        if (list == null || list.size() < no + 1) {
            return list;
        }

        List<T> retainList = new ArrayList<T>();
        for (int i = 0; i < no; i++) {
            retainList.add(list.get(i));
        }

        return retainList;
    }

    public static <T> List<T> retainEnd(List<T> list, int no) {
        if (list == null || list.size() < no + 1) {
            return list;
        }

        int size = list.size();

        List<T> retainList = new ArrayList<T>();
        for (int i = size - no; i < size; i++) {
            retainList.add(list.get(i));
        }

        return retainList;
    }

    public static Object first(Object obj) {
        return get(obj, 0);
    }

    public static Object last(Object obj) {
        return get(obj, size(obj) - 1);
    }

    public static <T> List<T> sort(List<T> list, Comparator<? super T> c) {
        if (list == null) {
            return null;
        }
        list.sort(c);
        return list;
    }

    public static <T> List<T> sort(List<T> list) {
        return sort(list, Comparator.comparing(T::toString));
    }

    public static <T> List<T> sublist(List<T> list, int start, int end) {
        List<T> sublist = new ArrayList<>();
        for (int i = start; i < end; i++) {
            if (i >= 0 && i < list.size()) {
                sublist.add(list.get(i));
            }
        }
        return sublist;
    }

    public static <T> List<T> sublist(List<T> list, int start) {
        return sublist(list, start, list.size());
    }

    public static <T> List<T> toListFromMap(Map<?, T> map) {
        if (map == null) {
            return null;
        }

        List<T> list = new ArrayList<T>();
        for (Map.Entry<?, T> each : map.entrySet()) {
            list.add(each.getValue());
        }
        return list;
    }

    public static <T> List<T> shuffleList(List<T> list) {
        Collections.shuffle(list);
        return list;
    }

    public static Map convertToSafeMap(Map m) {
        Map safeMap = new ConcurrentHashMap();
        for (Object each : m.entrySet()) {
            Map.Entry entry = (Map.Entry) each;
            safeMap.put(entry.getKey(), entry.getValue());
        }
        return safeMap;
    }

    public static <T extends Number> List<T> retailAll(List<List<T>> lists) {
        if (CollectionUtils.isEmpty(lists)) {
            return null;
        }
        List<T> temp = lists.get(0);

        for (int i = 1; i < lists.size(); i++) {
            temp.retainAll(lists.get(i));
            if (CollectionUtils.isEmpty(temp)) {
                break;
            }
        }
        return temp;
    }

    public static String join(Collection<String> col, String sep) {
        if (CollectionUtils.isEmpty(col)) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        for (String s : col) {
            sb.append(sep.concat(s));
        }
        return sb.toString().substring(1);
    }

    public static Collection<String> split(String s, String sep) {
        if (StringUtils.isEmpty(s)) {
            return null;
        }
        return Arrays.asList(s.split(sep));
    }

    public static boolean isCollection(Object obj) {
        return obj instanceof Collection || obj instanceof Map;
    }

    /**
     * 将一组数据固定分组，每组n个元素
     *
     * @param source 要分组的数据源
     * @param n      每组n个元素
     */
    public static <T> List<List<T>> fixedGrouping(List<T> source, int n) {
        if (source == null || source.size() == 0 || n <= 0) {
            return null;
        }
        int remainder = source.size() % n;
        int size = source.size() / n;
        List<List<T>> result = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            result.add(source.subList(i * n, (i + 1) * n));
        }
        if (remainder > 0) {
            result.add(source.subList(size * n, size * n + remainder));
        }
        return result;
    }

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");
        list.add("5");
        List<List<String>> result1 = fixedGrouping(list, 2);
        List<List<String>> result2 = fixedGrouping(list, 3);
        System.out.println(result1);
        System.out.println(result2);
    }
}
